﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Bymed.SpineScan.DataModel;
using Bymed.SpineScan.WPF.Model;
using Bymed.SpineScan.WPF.Shared;
using Bymed.SpineScan.WPF.ViewModel.TestItemViewModel;

namespace Bymed.SpineScan.WPF.ViewModel
{
    public class AllTestItemsViewModel : MyViewModelBase
    {
        //protected IList<SingleTestItemViewModel> TestItemList = new List<SingleTestItemViewModel>();

        /// <summary>
        /// Initializes a new instance of the AllTestItemsViewModel class.
        /// </summary>
        public AllTestItemsViewModel(IDataService dataService)
            : base(dataService) { }

        /// <summary>
        /// Generate selected TestItem list.
        /// </summary>
        public virtual void GenerateSelectedTestItemList()
        {
            TestItemList.Clear();

            TryAddTestItem(ScoliosisATI);
            TryAddTestItem(Kyphosis);
            TryAddTestItem(CervicalLateralBending);
            TryAddTestItem(ThoracicLateralBending);
            TryAddTestItem(LumbarLateralBending);
            TryAddTestItem(CervicalFlexExt);
            TryAddTestItem(ThoracicFlexExt);
            TryAddTestItem(LumbarFlexExt);
            TryAddTestItem(CervicalRotation);
            TryAddTestItem(ThoracicRotation);
            TryAddTestItem(LumbarRotation);
            TryAddTestItem(HeadBalance);
            TryAddTestItem(ShouldersBalance);
            TryAddTestItem(PelvicBalance);

            foreach (var item in SelectedCustomizedTestItemList)
            {
                TestItemList.Add(ViewModelHelper.CreateCustomizedTestItemViewModel(item));
            }
        }

        /// <summary>
        /// The <see cref="TestItemList" /> property's name.
        /// </summary>
        public const string TestItemListPropertyName = "TestItemList";

        private ObservableCollection<SingleTestItemViewModel> _testItemList = new ObservableCollection<SingleTestItemViewModel>();

        /// <summary>
        /// Sets and gets the TestItemList property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public ObservableCollection<SingleTestItemViewModel> TestItemList
        {
            get
            {
                return _testItemList;
            }

            set
            {
                if (_testItemList == value)
                {
                    return;
                }

                RaisePropertyChanging(TestItemListPropertyName);
                _testItemList = value;
                RaisePropertyChanged(TestItemListPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="SelectedCustomizedTestItemList" /> property's name.
        /// </summary>
        public const string SelectedCustomizedTestItemListPropertyName = "SelectedCustomizedTestItemList";

        private ObservableCollection<CustomizedTestItem> _selectedCustomizedTestItemList = new ObservableCollection<CustomizedTestItem>();

        /// <summary>
        /// Sets and gets the SelectedCustomizedTestItemList property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public ObservableCollection<CustomizedTestItem> SelectedCustomizedTestItemList
        {
            get
            {
                return _selectedCustomizedTestItemList;
            }

            set
            {
                if (_selectedCustomizedTestItemList == value)
                {
                    return;
                }

                RaisePropertyChanging(SelectedCustomizedTestItemListPropertyName);
                _selectedCustomizedTestItemList = value;
                RaisePropertyChanged(SelectedCustomizedTestItemListPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="ScoliosisATI" /> property's name.
        /// </summary>
        public const string ScoliosisATIPropertyName = "ScoliosisATI";

        private TestItemScoliosisATIViewModel _scoliosisATI = new TestItemScoliosisATIViewModel(null);

        /// <summary>
        /// Sets and gets the ScoliosisATI property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemScoliosisATIViewModel ScoliosisATI
        {
            get
            {
                return _scoliosisATI;
            }

            set
            {
                if (_scoliosisATI == value)
                {
                    return;
                }

                RaisePropertyChanging(ScoliosisATIPropertyName);
                _scoliosisATI = value;
                RaisePropertyChanged(ScoliosisATIPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="Kyphosis" /> property's name.
        /// </summary>
        public const string KyphosisPropertyName = "Kyphosis";

        private TestItemKyphosisViewModel _kyphosis = new TestItemKyphosisViewModel(null);

        /// <summary>
        /// Sets and gets the Kyphosis property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemKyphosisViewModel Kyphosis
        {
            get
            {
                return _kyphosis;
            }

            set
            {
                if (_kyphosis == value)
                {
                    return;
                }

                RaisePropertyChanging(KyphosisPropertyName);
                _kyphosis = value;
                RaisePropertyChanged(KyphosisPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="CervicalFlexExt" /> property's name.
        /// </summary>
        public const string CervicalFlexExtPropertyName = "CervicalFlexExt";

        private TestItemCervicalFlexionExtensionViewModel _cervicalFlexExt = new TestItemCervicalFlexionExtensionViewModel(null);

        /// <summary>
        /// Sets and gets the CervicalFlexExt property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemCervicalFlexionExtensionViewModel CervicalFlexExt
        {
            get
            {
                return _cervicalFlexExt;
            }

            set
            {
                if (_cervicalFlexExt == value)
                {
                    return;
                }

                RaisePropertyChanging(CervicalFlexExtPropertyName);
                _cervicalFlexExt = value;
                RaisePropertyChanged(CervicalFlexExtPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="ThoracicFlexExt" /> property's name.
        /// </summary>
        public const string ThoracicFlexExtPropertyName = "ThoracicFlexExt";

        private TestItemThoracicFlexionExtensionViewModel _thoracicFlexExt = new TestItemThoracicFlexionExtensionViewModel(null);

        /// <summary>
        /// Sets and gets the ThoracicFlexExt property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemThoracicFlexionExtensionViewModel ThoracicFlexExt
        {
            get
            {
                return _thoracicFlexExt;
            }

            set
            {
                if (_thoracicFlexExt == value)
                {
                    return;
                }

                RaisePropertyChanging(ThoracicFlexExtPropertyName);
                _thoracicFlexExt = value;
                RaisePropertyChanged(ThoracicFlexExtPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="LumbarFlexExt" /> property's name.
        /// </summary>
        public const string LumbarFlexExtPropertyName = "LumbarFlexExt";

        private TestItemLumbarFlexionExtensionViewModel _lumbarFlexExt = new TestItemLumbarFlexionExtensionViewModel(null);

        /// <summary>
        /// Sets and gets the LumbarFlexExt property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemLumbarFlexionExtensionViewModel LumbarFlexExt
        {
            get
            {
                return _lumbarFlexExt;
            }

            set
            {
                if (_lumbarFlexExt == value)
                {
                    return;
                }

                RaisePropertyChanging(LumbarFlexExtPropertyName);
                _lumbarFlexExt = value;
                RaisePropertyChanged(LumbarFlexExtPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="CervicalLateralBending" /> property's name.
        /// </summary>
        public const string CervicalLateralBendingPropertyName = "CervicalLateralBending";

        private TestItemCervicalLateralBendingViewModel _cervicalLateralBending = new TestItemCervicalLateralBendingViewModel(null);

        /// <summary>
        /// Sets and gets the CervicalLateralBending property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemCervicalLateralBendingViewModel CervicalLateralBending
        {
            get
            {
                return _cervicalLateralBending;
            }

            set
            {
                if (_cervicalLateralBending == value)
                {
                    return;
                }

                RaisePropertyChanging(CervicalLateralBendingPropertyName);
                _cervicalLateralBending = value;
                RaisePropertyChanged(CervicalLateralBendingPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="ThoracicLateralBending" /> property's name.
        /// </summary>
        public const string ThoracicLateralBendingPropertyName = "ThoracicLateralBending";

        private TestItemThoracicLateralBendingViewModel _thoracicLateralBending = new TestItemThoracicLateralBendingViewModel(null);

        /// <summary>
        /// Sets and gets the ThoracicLateralBending property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemThoracicLateralBendingViewModel ThoracicLateralBending
        {
            get
            {
                return _thoracicLateralBending;
            }

            set
            {
                if (_thoracicLateralBending == value)
                {
                    return;
                }

                RaisePropertyChanging(ThoracicLateralBendingPropertyName);
                _thoracicLateralBending = value;
                RaisePropertyChanged(ThoracicLateralBendingPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="LumbarLateralBending" /> property's name.
        /// </summary>
        public const string LumbarLateralBendingPropertyName = "LumbarLateralBending";

        private TestItemLumbarLateralBendingViewModel _lumbarLateralBending = new TestItemLumbarLateralBendingViewModel(null);

        /// <summary>
        /// Sets and gets the LumbarLateralBending property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemLumbarLateralBendingViewModel LumbarLateralBending
        {
            get
            {
                return _lumbarLateralBending;
            }

            set
            {
                if (_lumbarLateralBending == value)
                {
                    return;
                }

                RaisePropertyChanging(LumbarLateralBendingPropertyName);
                _lumbarLateralBending = value;
                RaisePropertyChanged(LumbarLateralBendingPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="CervicalRotation" /> property's name.
        /// </summary>
        public const string CervicalRotationPropertyName = "CervicalRotation";

        private TestItemCervicalRotationViewModel _cervicalRotation = new TestItemCervicalRotationViewModel(null);

        /// <summary>
        /// Sets and gets the CervicalRotation property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemCervicalRotationViewModel CervicalRotation
        {
            get
            {
                return _cervicalRotation;
            }

            set
            {
                if (_cervicalRotation == value)
                {
                    return;
                }

                RaisePropertyChanging(CervicalRotationPropertyName);
                _cervicalRotation = value;
                RaisePropertyChanged(CervicalRotationPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="ThoracicRotation" /> property's name.
        /// </summary>
        public const string ThoracicRotationPropertyName = "ThoracicRotation";

        private TestItemThoracicRotationViewModel _thoracicRotation = new TestItemThoracicRotationViewModel(null);

        /// <summary>
        /// Sets and gets the ThoracicRotation property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemThoracicRotationViewModel ThoracicRotation
        {
            get
            {
                return _thoracicRotation;
            }

            set
            {
                if (_thoracicRotation == value)
                {
                    return;
                }

                RaisePropertyChanging(ThoracicRotationPropertyName);
                _thoracicRotation = value;
                RaisePropertyChanged(ThoracicRotationPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="LumbarRotation" /> property's name.
        /// </summary>
        public const string LumbarRotationPropertyName = "LumbarRotation";

        private TestItemLumbarRotationViewModel _lumbarRotation = new TestItemLumbarRotationViewModel(null);

        /// <summary>
        /// Sets and gets the LumbarRotation property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemLumbarRotationViewModel LumbarRotation
        {
            get
            {
                return _lumbarRotation;
            }

            set
            {
                if (_lumbarRotation == value)
                {
                    return;
                }

                RaisePropertyChanging(LumbarRotationPropertyName);
                _lumbarRotation = value;
                RaisePropertyChanged(LumbarRotationPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="HeadBalance" /> property's name.
        /// </summary>
        public const string HeadBalancePropertyName = "HeadBalance";

        private TestItemHeadBalanceViewModel _headBalance = new TestItemHeadBalanceViewModel(null);

        /// <summary>
        /// Sets and gets the HeadBalance property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemHeadBalanceViewModel HeadBalance
        {
            get
            {
                return _headBalance;
            }

            set
            {
                if (_headBalance == value)
                {
                    return;
                }

                RaisePropertyChanging(HeadBalancePropertyName);
                _headBalance = value;
                RaisePropertyChanged(HeadBalancePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="ShouldersBalance" /> property's name.
        /// </summary>
        public const string ShouldersBalancePropertyName = "ShouldersBalance";

        private TestItemShouldersBalanceViewModel _shouldersBalance = new TestItemShouldersBalanceViewModel(null);

        /// <summary>
        /// Sets and gets the ShouldersBalance property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemShouldersBalanceViewModel ShouldersBalance
        {
            get
            {
                return _shouldersBalance;
            }

            set
            {
                if (_shouldersBalance == value)
                {
                    return;
                }

                RaisePropertyChanging(ShouldersBalancePropertyName);
                _shouldersBalance = value;
                RaisePropertyChanged(ShouldersBalancePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="PelvicBalance" /> property's name.
        /// </summary>
        public const string PelvicBalancePropertyName = "PelvicBalance";

        private TestItemPelvicBalanceViewModel _pelvicBalance = new TestItemPelvicBalanceViewModel(null);

        /// <summary>
        /// Sets and gets the PelvicBalance property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public TestItemPelvicBalanceViewModel PelvicBalance
        {
            get
            {
                return _pelvicBalance;
            }

            set
            {
                if (_pelvicBalance == value)
                {
                    return;
                }

                RaisePropertyChanging(PelvicBalancePropertyName);
                _pelvicBalance = value;
                RaisePropertyChanged(PelvicBalancePropertyName);
            }
        }

        /// <summary>
        /// Try to add the TestItem into selected TestItem list if it is selected and it does NOT exist yet.
        /// </summary>
        /// <param name="testItem">The TestItem might need to be added into selected TestItem list.</param>
        private void TryAddTestItem(SingleTestItemViewModel testItem)
        {
            if (testItem.IsSelected && !TestItemList.Contains(testItem))
            {
                TestItemList.Add(testItem);
            }
        }
    }
}
